package com.gui;

import com.swingson.exceptions.ErrorMessageException;
import com.utils.XPathEngine;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * @author sad
 */
public class CodeProcessor {

    private final Map<String, String> barcodeToInternalRefMap = new HashMap<String, String>();
    private String userPassword = "ryRnNZQV";
    private String userLogin = "lmb";
    private String hostUrl = "https://wom.lundimatin.biz";

    public CodeProcessor() {
        try {
            Properties props=new Properties();
            try (FileInputStream stream = new FileInputStream(new File("./settings.txt"))) {
                props.load(stream);
                hostUrl=props.getProperty("url", "https://wom.lundimatin.biz");
                userLogin=props.getProperty("login", "lmb");
                userPassword=props.getProperty("password", "ryRnNZQV");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    
    
    public void loadFromFile() {
        barcodeToInternalRefMap.clear();
        File barcodeDatabaseFile = new File("./barcodes.txt");
        if (!barcodeDatabaseFile.exists()) {
            return;
        }

        try (Scanner scanner = new Scanner(barcodeDatabaseFile)) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine().trim();
                line = Utils.removeUTF8BOM(line);
                if (!line.isEmpty()) {
                    String[] values = line.split("\t|\t");
                    barcodeToInternalRefMap.put(values[0], values[2]);
                }
            }
        } catch (FileNotFoundException ex) {
            throw new RuntimeException(ex);
        }
    }

    public void reloadFromServer() {
        try {
            String soapRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                    + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"urn:Liaison\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns2=\"http://schemas.xmlsoap.org/ws/2002/07/utility\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
                    + "<SOAP-ENV:Header>"
                    + "<ns2:UsernameToken><Password>" + userPassword + "</Password><Username>" + userLogin + "</Username></ns2:UsernameToken>"
                    + "</SOAP-ENV:Header>"
                    + "<SOAP-ENV:Body>"
                    + "<ns1:get_stocks_by_idstock>"
                    + "<param0 xsi:type=\"SOAP-ENC:Struct\">"
                    + "<_params xsi:type=\"xsd:int\">1</_params>"
                    + "<_conversion SOAP-ENC:arrayType=\"xsd:ur-type[0]\" xsi:type=\"SOAP-ENC:Array\"/>"
                    + "</param0>"
                    + "</ns1:get_stocks_by_idstock>"
                    + "</SOAP-ENV:Body>"
                    + "</SOAP-ENV:Envelope>";
            URL url = new URL(hostUrl + "/api.php?ref_api=stocks");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.addRequestProperty("SOAPAction", "urn:Liaison#get_stocks_by_idstock");
            connection.setDoOutput(true);
            IOUtils.write(soapRequest, connection.getOutputStream());
            if (!(connection.getResponseCode() == 200)) {
                throw new ErrorMessageException("Server " + hostUrl + " returned response code " + connection.getResponseCode() + " with message " + connection.getResponseMessage());
            }

            String response = IOUtils.toString(connection.getInputStream(),"UTF-8");
            parseServerResponse(response);
            loadFromFile();
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    private void parseServerResponse(String value) throws FileNotFoundException, UnsupportedEncodingException {
        XPathEngine xpathEngine = new XPathEngine(value);
        NodeList nodes = xpathEngine.getNodeSetByXPath("/Envelope/Body/get_stocks_by_idstockResponse/return/item/key[text()='data']/../value/item");
        if (nodes == null || nodes.getLength() == 0) {
            throw new ErrorMessageException("Server response does not contain necessary answer");
        }
        File file = new File("./barcodes.txt");
        try (PrintStream stream = new PrintStream(file, "UTF-8")) {
            for (int i = 0; i < nodes.getLength(); i++) {
                Element node = (Element) nodes.item(i);
                String barcode=xpathEngine.getTextValueByXPath("item/key[text()='code_barre']/../value", node);
                String ref=xpathEngine.getTextValueByXPath("item/key[text()='ref_interne']/../value", node);
                stream.print(barcode);
                stream.print("\t|\t");
                stream.print(ref);
                stream.println();
            }
        }

    }

    public String convertBarcodeToInternalRef(String barcode) {
        return barcodeToInternalRefMap.get(barcode);
    }
}
